<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Ploy4J - 管理Git仓库配置</title>
    <meta name="_csrf" th:content="${_csrf?.token}"/>
    <meta name="_csrf_header" th:content="${_csrf != null ? _csrf.headerName : ''}"/>
    <link rel="icon" href="/img/favicon.ico" type="image/x-icon">
    <!-- 引入Bootstrap图标 -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
</head>
<body>
    <div class="goploy-panel ploy4j-page-content" id="git-repo-management-content">
        <!-- 工具栏 -->
        <div class="toolbar d-flex align-items-center mb-3 p-2 rounded">
            <input type="text" id="projectNameFilter" class="form-control form-control-sm me-2" placeholder="按项目名称筛选" style="max-width: 180px;">
            <input type="text" id="repositoryUrlFilter" class="form-control form-control-sm me-2" placeholder="按仓库URL筛选" style="max-width: 180px;">
            <div class="ms-auto d-flex align-items-center">
                <button class="btn btn-primary btn-sm d-flex align-items-center" id="newRepoBtn">
                    <i class="bi bi-plus-lg me-1"></i> 新建Git仓库
                </button>
            </div>
        </div>
        
        <!-- Git仓库表格 -->
        <div class="table-responsive">
            <table class="table table-hover table-sm caption-top goploy-table">
                <thead class="table-light">
                    <tr>
                        <th style="width: 5%;">ID</th>
                        <th>项目名称</th>
                        <th>仓库URL</th>
                        <th>默认分支</th>
                        <th class="text-center">创建时间</th>
                        <th class="text-center">更新时间</th>
                        <th class="text-center" style="width: 15%;">操作</th>
                    </tr>
                </thead>
                <tbody id="gitRepoTableBody">
                    <!-- Git仓库数据行将通过JavaScript动态插入 -->
                </tbody>
            </table>
        </div>
        
        <!-- 无数据提示 -->
        <div id="noGitReposMessage" class="alert alert-info text-center" style="display: none;">
            暂无Git仓库配置，请点击右上角 "新建Git仓库" 按钮进行添加。
        </div>

        <!-- Git仓库配置模态框 -->
        <div class="modal fade" id="gitRepoConfigModal" tabindex="-1" aria-labelledby="gitRepoConfigModalLabel" aria-hidden="true">
            <div class="modal-dialog modal-lg">
                <div class="modal-content">
                    <form id="gitRepoConfigForm">
                        <input type="hidden" id="repoId" name="id">
                        <div class="modal-header">
                            <h5 class="modal-title" id="gitRepoConfigModalLabel">新建Git仓库</h5>
                            <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                        </div>
                        <div class="modal-body">
                            <div class="mb-3">
                                <label for="projectName" class="form-label">项目名称 <span class="text-danger">*</span></label>
                                <input type="text" class="form-control" id="projectName" name="projectName" required>
                            </div>
                            <div class="mb-3">
                                <label for="repositoryUrl" class="form-label">仓库URL <span class="text-danger">*</span></label>
                                <input type="url" class="form-control" id="repositoryUrl" name="repositoryUrl" required>
                                <small class="form-text text-muted">例如: https://gitee.com/username/project.git</small>
                            </div>
                            <div class="mb-3">
                                <label for="defaultBranch" class="form-label">默认分支 <span class="text-danger">*</span></label>
                                <input type="text" class="form-control" id="defaultBranch" name="defaultBranch" required>
                                <small class="form-text text-muted">例如: master, main, develop</small>
                            </div>
                            <div class="mb-3">
                                <label for="giteeToken" class="form-label">Gitee Token (可选)</label>
                                <div class="input-group">
                                    <input type="password" class="form-control" id="giteeToken" name="giteeToken">
                                    <button class="btn btn-outline-secondary toggle-password" type="button" title="显示/隐藏密码">
                                        <i class="bi bi-eye"></i>
                                    </button>
                                </div>
                                <small id="tokenHelpBlock" class="form-text text-muted">
                                    如果仓库需要认证访问，请提供Token。编辑时若不修改Token则无需填写。
                                </small>
                            </div>
                            <div id="testConnectionResult" class="mt-3" style="display: none;"></div>
                        </div>
                        <div class="modal-footer">
                            <button type="button" class="btn btn-outline-secondary me-auto" id="testConnectionBtn">
                                <i class="bi bi-shield-check me-1"></i> 测试连接
                            </button>
                            <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
                            <button type="submit" class="btn btn-primary" id="saveGitRepoBtn">保存</button>
                        </div>
                    </form>
                </div>
            </div>
        </div>
        
        <!-- 操作结果通知容器 -->
        <div id="gitRepoNotificationsContainer" style="position: fixed; top: 80px; right: 20px; z-index: 1055;"></div>
    </div>

<script>
// 确保initGitRepoManagement函数在全局作用域中定义
window.initGitRepoManagement = function() {
    console.log("正在初始化Git仓库管理...");
    
    // 使用立即执行函数封装功能模块
    const GitRepoManagement = (function() {
        // 私有变量
        let repoData = [];
        const csrfToken = document.querySelector('meta[name="_csrf"]')?.getAttribute('content') || '';
        const csrfHeader = document.querySelector('meta[name="_csrf_header"]')?.getAttribute('content') || '';
        
        // DOM元素缓存
        const elements = {
            repoForm: document.getElementById('gitRepoConfigForm'),
            repoModal: null, // 将在initBootstrapModal中设置
            repoTableBody: document.getElementById('gitRepoTableBody'),
            testConnectionBtn: document.getElementById('testConnectionBtn'),
            saveRepoBtn: document.getElementById('saveGitRepoBtn'),
            refreshBtn: document.getElementById('refreshGitRepoListBtn'),
            projectNameFilter: document.getElementById('projectNameFilter'),
            repoUrlFilter: document.getElementById('repositoryUrlFilter')
        };
        
        // 初始化模态框
        function initModal() {
            // 检查Bootstrap是否已加载
            if (typeof bootstrap === 'undefined') {
                console.error('Bootstrap 未加载，尝试动态加载...');
                const bsScript = document.createElement('script');
                bsScript.src = 'https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js';
                bsScript.onload = function() {
                    console.log('Bootstrap 已动态加载');
                    initBootstrapModal();
                };
                document.head.appendChild(bsScript);
            } else {
                initBootstrapModal();
            }
        }
        
        function initBootstrapModal() {
            // 获取模态框元素
            const repoModal = document.getElementById('gitRepoConfigModal');
            if (!repoModal) {
                console.error('找不到Git仓库模态框元素: gitRepoConfigModal');
                return;
            }
            
            // 使用Bootstrap API初始化模态框
            try {
                const modal = new bootstrap.Modal(repoModal);
                elements.repoModal = modal; // 保存模态框实例
                
                // 监听模态框隐藏事件，确保清理背景蒙版
                repoModal.addEventListener('hidden.bs.modal', function() {
                    // 重置表单
                    resetForm();
                    
                    // 移除可能残留的模态背景
                    const backdrops = document.querySelectorAll('.modal-backdrop');
                    backdrops.forEach(backdrop => {
                        backdrop.remove();
                    });
                    
                    // 移除body上的modal-open类
                    document.body.classList.remove('modal-open');
                    document.body.style.removeProperty('overflow');
                    document.body.style.removeProperty('padding-right');
                });
                
                // 为新建仓库按钮添加事件监听
                const newRepoBtn = document.getElementById('newRepoBtn');
                if (newRepoBtn) {
                    newRepoBtn.addEventListener('click', function() {
                        // 重置表单
                        resetForm();
                        
                        // 更新标题
                        const modalTitle = document.getElementById('gitRepoConfigModalLabel');
                        if (modalTitle) modalTitle.textContent = '新建Git仓库配置';
                        
                        // 清空测试结果
                        const testConnResult = document.getElementById('testConnectionResult');
                        if (testConnResult) {
                            testConnResult.style.display = 'none';
                            testConnResult.textContent = '';
                        }
                        
                        // 显示模态框
                        modal.show();
                    });
                    console.log('已为新建Git仓库按钮绑定事件');
                } else {
                    console.error('找不到新建Git仓库按钮: newRepoBtn');
                }
                
                // 为模态框关闭按钮添加事件监听
                const closeButtons = repoModal.querySelectorAll('[data-bs-dismiss="modal"]');
                closeButtons.forEach(button => {
                    button.addEventListener('click', function() {
                        modal.hide();
                    });
                });
            } catch (error) {
                console.error('初始化模态框失败:', error);
            }
        }
        
        // 重置表单
        function resetForm() {
            if (elements.repoForm) {
                elements.repoForm.reset();
                elements.repoForm.classList.remove('was-validated');
                elements.repoForm.elements.id.value = '';
                
                // 重置表单状态
                const invalidFeedbacks = elements.repoForm.querySelectorAll('.invalid-feedback');
                invalidFeedbacks.forEach(el => el.style.display = 'none');
                
                const formControls = elements.repoForm.querySelectorAll('.form-control');
                formControls.forEach(el => {
                    el.classList.remove('is-invalid');
                    el.classList.remove('is-valid');
                });
            }
        }
        
        // 加载Git仓库数据
        function loadRepoData() {
            showLoading(elements.repoTableBody);
            
            fetch('/api/git-repo-configs')
                .then(response => {
                    if (!response.ok) {
                        throw new Error('Git仓库数据加载失败: ' + response.status);
                    }
                    return response.json();
                })
                .then(data => {
                    repoData = data;
                    renderRepoTable();
                })
                .catch(error => {
                    console.error('加载Git仓库列表出错:', error);
                    showErrorMessage(elements.repoTableBody, '加载Git仓库列表失败: ' + error.message);
                });
        }
        
        // 渲染Git仓库表格
        function renderRepoTable() {
            const tableBody = elements.repoTableBody;
            if (!tableBody) {
                console.error('找不到Git仓库表格主体元素');
                return;
            }
            
            tableBody.innerHTML = '';
            
            if (!repoData || repoData.length === 0) {
                const emptyRow = document.createElement('tr');
                emptyRow.innerHTML = `
                    <td colspan="7" class="text-center py-3">
                        <div class="alert alert-info mb-0">
                            <i class="bi bi-info-circle me-2"></i>暂无Git仓库配置数据
                        </div>
                    </td>
                `;
                tableBody.appendChild(emptyRow);
                return;
            }
            
            repoData.forEach((repo) => {
                const row = document.createElement('tr');
                row.innerHTML = `
                    <td>${repo.id || '-'}</td>
                    <td>${escapeHtml(repo.projectName)}</td>
                    <td>${escapeHtml(repo.repositoryUrl)}</td>
                    <td>${escapeHtml(repo.defaultBranch || 'main')}</td>
                    <td class="text-center">${formatDateTime(repo.createdAt)}</td>
                    <td class="text-center">${formatDateTime(repo.updatedAt)}</td>
                    <td class="text-center">
                        <div class="btn-group btn-group-sm">
                            <button type="button" class="btn btn-outline-info test-conn-btn" data-id="${repo.id}" title="测试连接">
                                <i class="bi bi-shield-check"></i>
                            </button>
                            <button type="button" class="btn btn-outline-primary edit-repo-btn" data-id="${repo.id}" title="编辑">
                                <i class="bi bi-pencil-square"></i>
                            </button>
                            <button type="button" class="btn btn-outline-danger delete-repo-btn" data-id="${repo.id}" title="删除">
                                <i class="bi bi-trash"></i>
                            </button>
                        </div>
                    </td>
                `;
                tableBody.appendChild(row);
                
                // 为按钮添加事件监听
                const testBtn = row.querySelector('.test-conn-btn');
                if (testBtn) {
                    testBtn.addEventListener('click', () => testRepoConnection(repo.id, testBtn));
                }
                
                const editBtn = row.querySelector('.edit-repo-btn');
                if (editBtn) {
                    editBtn.addEventListener('click', () => editRepo(repo.id));
                }
                
                const deleteBtn = row.querySelector('.delete-repo-btn');
                if (deleteBtn) {
                    deleteBtn.addEventListener('click', () => confirmDeleteRepo(repo.id, repo.projectName));
                }
            });
        }
        
        // 编辑Git仓库
        function editRepo(id) {
            const repo = repoData.find(r => r.id === id);
            if (!repo) {
                console.error('未找到ID为 ' + id + ' 的Git仓库数据');
                return;
            }
            
            // 填充表单
            const form = elements.repoForm;
            if (form) {
                form.elements.id.value = repo.id;
                form.elements.projectName.value = repo.projectName || '';
                form.elements.repositoryUrl.value = repo.repositoryUrl || '';
                form.elements.defaultBranch.value = repo.defaultBranch || '';
                form.elements.giteeToken.value = ''; // 出于安全考虑，不回填令牌
                
                // 显示模态框
                document.getElementById('gitRepoConfigModalLabel').textContent = '编辑Git仓库配置';
                const modal = new bootstrap.Modal(document.getElementById('gitRepoConfigModal'));
                modal.show();
            }
        }
        
        // 确认删除仓库
        function confirmDeleteRepo(id, name) {
            if (confirm(`确认要删除仓库 "${name}" 吗？`)) {
                deleteRepo(id);
            }
        }
        
        // 删除仓库
        function deleteRepo(id) {
            const headers = {
                'Content-Type': 'application/json'
            };
            
            if (csrfToken && csrfHeader) {
                headers[csrfHeader] = csrfToken;
            }
            
            fetch(`/api/git-repo-configs/${id}`, {
                method: 'DELETE',
                headers: headers
            })
            .then(response => {
                if (!response.ok) {
                    throw new Error('删除失败: ' + response.status);
                }
                showSuccessToast('Git仓库配置删除成功');
                loadRepoData(); // 重新加载数据
            })
            .catch(error => {
                console.error('删除Git仓库配置出错:', error);
                showErrorToast('删除失败: ' + error.message);
            });
        }
        
        // 测试仓库连接
        function testRepoConnection(id, testBtn) {
            const repo = repoData.find(r => r.id === id);
            if (!repo) {
                console.error('未找到ID为 ' + id + ' 的Git仓库数据');
                return;
            }
            
            testBtn.disabled = true;
            testBtn.innerHTML = '<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>';
            
            const headers = {
                'Content-Type': 'application/json'
            };
            
            if (csrfToken && csrfHeader) {
                headers[csrfHeader] = csrfToken;
            }
            
            fetch(`/api/git-repo-configs/${id}/test-connection`, {
                method: 'POST',
                headers: headers
            })
            .then(response => response.json())
            .then(data => {
                showSuccessToast(data.message);
            })
            .catch(error => {
                console.error('测试连接失败:', error);
                showErrorToast('测试连接失败: ' + error.message);
            })
            .finally(() => {
                testBtn.disabled = false;
                testBtn.innerHTML = '<i class="bi bi-shield-check"></i>';
            });
        }
        
        // 添加日期时间格式化函数
        function formatDateTime(dateTimeString) {
            if (!dateTimeString) return '-';
            try {
                const date = new Date(dateTimeString);
                return date.toLocaleString('zh-CN', {
                    year: 'numeric',
                    month: '2-digit',
                    day: '2-digit',
                    hour: '2-digit',
                    minute: '2-digit',
                    second: '2-digit'
                });
            } catch (e) {
                return dateTimeString;
            }
        }
        
        // 保存仓库配置
        function saveRepoConfig(event) {
            event.preventDefault();
            
            const form = elements.repoForm;
            if (!form) return;
            
            // 表单验证
            if (!form.checkValidity()) {
                form.classList.add('was-validated');
                return;
            }
            
            // 构建表单数据
            const formData = {
                id: form.elements.id.value || null,
                projectName: form.elements.projectName.value,
                repositoryUrl: form.elements.repositoryUrl.value,
                defaultBranch: form.elements.defaultBranch.value || 'main',
                giteeToken: form.elements.giteeToken.value || null
            };
            
            const headers = {
                'Content-Type': 'application/json'
            };
            
            if (csrfToken && csrfHeader) {
                headers[csrfHeader] = csrfToken;
            }
            
            // 禁用保存按钮
            const saveBtn = elements.saveRepoBtn;
            if (saveBtn) {
                saveBtn.disabled = true;
                saveBtn.innerHTML = '<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> 保存中...';
            }
            
            // 决定请求方法
            const method = formData.id ? 'PUT' : 'POST';
            const url = formData.id ? `/api/git-repo-configs/${formData.id}` : '/api/git-repo-configs';
            
            // 发送请求
            fetch(url, {
                method: method,
                headers: headers,
                body: JSON.stringify(formData)
            })
            .then(response => {
                if (!response.ok) {
                    throw new Error('保存失败: ' + response.status);
                }
                return response.json();
            })
            .then(data => {
                // 显示成功提示
                showSuccessToast('Git仓库配置保存成功');
                
                // 关闭模态框并清理背景
                closeModal();
                
                // 重新加载数据
                loadRepoData();
            })
            .catch(error => {
                console.error('保存Git仓库配置出错:', error);
                showErrorToast('保存失败: ' + error.message);
            })
            .finally(() => {
                // 恢复保存按钮
                if (saveBtn) {
                    saveBtn.disabled = false;
                    saveBtn.innerHTML = '<i class="bi bi-check-circle"></i> 保存';
                }
            });
        }
        
        // 辅助函数: 显示加载状态
        function showLoading(container) {
            if (container) {
                container.innerHTML = `
                    <tr>
                        <td colspan="7" class="text-center py-4">
                            <div class="d-flex justify-content-center">
                                <div class="spinner-border text-primary" role="status">
                                    <span class="visually-hidden">加载中...</span>
                                </div>
                            </div>
                            <div class="mt-2">正在加载Git仓库配置...</div>
                        </td>
                    </tr>
                `;
            }
        }
        
        // 辅助函数: 显示错误消息
        function showErrorMessage(container, message) {
            if (container) {
                container.innerHTML = `
                    <tr>
                        <td colspan="7" class="text-center py-3">
                            <div class="alert alert-danger mb-0">
                                <i class="bi bi-exclamation-triangle-fill me-2"></i>${message}
                            </div>
                        </td>
                    </tr>
                `;
            }
        }
        
        // 辅助函数: 显示成功提示
        function showSuccessToast(message) {
            // 检查是否存在toast容器，如果没有则创建
            let toastContainer = document.getElementById('toastContainer');
            if (!toastContainer) {
                toastContainer = document.createElement('div');
                toastContainer.id = 'toastContainer';
                toastContainer.className = 'toast-container position-fixed bottom-0 end-0 p-3';
                document.body.appendChild(toastContainer);
            }
            
            // 创建新的toast元素
            const toastId = 'toast-' + Date.now();
            const toastElement = document.createElement('div');
            toastElement.className = 'toast align-items-center text-white bg-success border-0';
            toastElement.id = toastId;
            toastElement.setAttribute('role', 'alert');
            toastElement.setAttribute('aria-live', 'assertive');
            toastElement.setAttribute('aria-atomic', 'true');
            
            toastElement.innerHTML = `
                <div class="d-flex">
                    <div class="toast-body">
                        <i class="bi bi-check-circle-fill me-2"></i>${message}
                    </div>
                    <button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast" aria-label="Close"></button>
                </div>
            `;
            
            toastContainer.appendChild(toastElement);
            
            // 使用Bootstrap API显示toast
            if (typeof bootstrap !== 'undefined') {
                const toast = new bootstrap.Toast(toastElement, {
                    autohide: true,
                    delay: 3000
                });
                toast.show();
            }
        }
        
        // 辅助函数: 显示错误提示
        function showErrorToast(message) {
            // 检查是否存在toast容器，如果没有则创建
            let toastContainer = document.getElementById('toastContainer');
            if (!toastContainer) {
                toastContainer = document.createElement('div');
                toastContainer.id = 'toastContainer';
                toastContainer.className = 'toast-container position-fixed bottom-0 end-0 p-3';
                document.body.appendChild(toastContainer);
            }
            
            // 创建新的toast元素
            const toastId = 'toast-' + Date.now();
            const toastElement = document.createElement('div');
            toastElement.className = 'toast align-items-center text-white bg-danger border-0';
            toastElement.id = toastId;
            toastElement.setAttribute('role', 'alert');
            toastElement.setAttribute('aria-live', 'assertive');
            toastElement.setAttribute('aria-atomic', 'true');
            
            toastElement.innerHTML = `
                <div class="d-flex">
                    <div class="toast-body">
                        <i class="bi bi-exclamation-triangle-fill me-2"></i>${message}
                    </div>
                    <button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast" aria-label="Close"></button>
                </div>
            `;
            
            toastContainer.appendChild(toastElement);
            
            // 使用Bootstrap API显示toast
            if (typeof bootstrap !== 'undefined') {
                const toast = new bootstrap.Toast(toastElement, {
                    autohide: true,
                    delay: 5000
                });
                toast.show();
            }
        }
        
        // 辅助函数：HTML转义
        function escapeHtml(unsafe) {
            if (!unsafe) return '';
            return unsafe
                .replace(/&/g, "&amp;")
                .replace(/</g, "&lt;")
                .replace(/>/g, "&gt;")
                .replace(/"/g, "&quot;")
                .replace(/'/g, "&#039;");
        }
        
        // 初始化函数
        function init() {
            console.log('初始化Git仓库管理模块...');
            
            // 初始化模态框
            initModal();
            
            // 加载仓库数据
            loadRepoData();
            
            // 注册事件监听
            if (elements.repoForm) {
                elements.repoForm.addEventListener('submit', saveRepoConfig);
            }
            
            if (elements.testConnectionBtn) {
                elements.testConnectionBtn.addEventListener('click', testRepoConnection);
            }
        }
        
        // 返回公共API
        return {
            init: init,
            reloadData: loadRepoData
        };
    })();
    
    // 初始化Git仓库管理模块
    GitRepoManagement.init();
};

// 如果页面已经加载完毕，则直接初始化
if (document.readyState === 'complete' || document.readyState === 'interactive') {
    window.initGitRepoManagement();
} else {
    // 否则等待DOM加载完成后初始化
    document.addEventListener('DOMContentLoaded', window.initGitRepoManagement);
}
</script>
</body>
</html> 